WORD文档的读写比较复杂,包括标题、段落、正文、表格等,此处只是简单的读写word文档(2007及以上版本) 注意: 1.目标文档标题结构都是相邻的,没有相差两级及以上的标题 2.只读取文本 3.能简单设置格式,如标题加粗、段落首行缩进
需要的jar包
public class DealWordByPoi {
private Map orderMap =new HashMap();
public void init(String targetPath,String sourcePath){
InputStream is = null;
XWPFDocument doc=null;
OutputStream out=null;
try {
XWPFDocument createDoc = new XWPFDocument();
is = new FileInputStream(sourcePath);
doc = new XWPFDocument(is);
//获取段落
List paras=doc.getParagraphs();
for (XWPFParagraph para : paras){
// System.out.println(para.getCTP());//得到xml格式
// System.out.println(para.getStyleID());//段落级别
// System.out.println(para.getParagraphText());//段落内容
String titleLvl = getTitleLvl(doc,para);//获取段落级别
if("a5".equals(titleLvl)||"HTML".equals(titleLvl)||"".equals(titleLvl)||null==titleLvl){
titleLvl = "8";
}
// System.out.println(titleLvl+"-----");//0,1,2
if(!"8".equals(titleLvl)){
System.out.println(titleLvl+"===="+para.getParagraphText());
}
XWPFParagraph ctPara = createDoc.createParagraph();
//一个XWPFRun代表具有相同属性的一个区域。
XWPFRun ctRun = ctPara.createRun();
String ctText = para.getParagraphText();
ctRun.setFontFamily("宋体");//字体
ctRun.setFontSize(12);
if(null!=titleLvl&&!"".equals(titleLvl)&&!"8".equals(titleLvl)){
addCustomHeadingStyle(createDoc,titleLvl,Integer.parseInt(titleLvl));
String orderCode = getOrderCode(titleLvl);//获取编号
ctText = orderCode+" "+ctText;
ctRun.setBold(true);//标题加粗
ctRun.setFontSize(14);
ctPara.setStyle(titleLvl);
}else{//正文
ctPara.setIndentationFirstLine(567);//首行缩进:567==1厘米
// ctRun.setTextPosition(6);//设置行间距
}
ctRun.setText(ctText);//内容
}
out=new FileOutputStream(targetPath);
createDoc.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(null!=out){
out.close();
}
if(null!=is){
is.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Word中的大纲级别,可以通过getPPr().getOutlineLvl()直接提取,但需要注意,Word中段落级别,通过如下三种方式定义:
* 1、直接对段落进行定义;
* 2、对段落的样式进行定义;
* 3、对段落样式的基础样式进行定义。
* 因此,在通过“getPPr().getOutlineLvl()”提取时,需要依次在如上三处读取。
* @param doc
* @param para
* @return
*/
private String getTitleLvl(XWPFDocument doc, XWPFParagraph para) {
String titleLvl = "";
try {
//判断该段落是否设置了大纲级别
if (para.getCTP().getPPr().getOutlineLvl() != null) {
// System.out.println("getCTP()");
// System.out.println(para.getParagraphText());
// System.out.println(para.getCTP().getPPr().getOutlineLvl().getVal());
return String.valueOf(para.getCTP().getPPr().getOutlineLvl().getVal());
}
} catch (Exception e) {
}
try {
//判断该段落的样式是否设置了大纲级别
if (doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {
// System.out.println("getStyle");
// System.out.println(para.getParagraphText());
// System.out.println(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
return String.valueOf(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
}
} catch (Exception e) {
}
try {
//判断该段落的样式的基础样式是否设置了大纲级别
if (doc.getStyles().getStyle(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal())
.getCTStyle().getPPr().getOutlineLvl() != null) {
// System.out.println("getBasedOn");
// System.out.println(para.getParagraphText());
String styleName = doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();
// System.out.println(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
return String.valueOf(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
}
} catch (Exception e) {
}
try {
if(para.getStyleID()!=null){
return para.getStyleID();
}
} catch (Exception e) {
}
return titleLvl;
}
/**
* 增加自定义标题样式。这里用的是stackoverflow的源码
*
* @param docxDocument 目标文档
* @param strStyleId 样式名称
* @param headingLevel 样式级别
*/
private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
strStyleId = String.valueOf(Integer.parseInt(strStyleId)+1);
CTStyle ctStyle = CTStyle.Factory.newInstance();
ctStyle.setStyleId(strStyleId);
CTString styleName = CTString.Factory.newInstance();
styleName.setVal(strStyleId);
ctStyle.setName(styleName);
CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
indentNumber.setVal(BigInteger.valueOf(headingLevel));
// lower number > style is more prominent in the formats bar
ctStyle.setUiPriority(indentNumber);
CTOnOff onoffnull = CTOnOff.Factory.newInstance();
ctStyle.setUnhideWhenUsed(onoffnull);
// style shows up in the formats bar
ctStyle.setQFormat(onoffnull);
// style defines a heading of the given level
CTPPr ppr = CTPPr.Factory.newInstance();
ppr.setOutlineLvl(indentNumber);
ctStyle.setPPr(ppr);
XWPFStyle style = new XWPFStyle(ctStyle);
// is a null op if already defined
XWPFStyles styles = docxDocument.createStyles();
style.setType(STStyleType.PARAGRAPH);
styles.addStyle(style);
}
/**
* 获取标题编号
* @param titleLvl
* @return
*/
private String getOrderCode(String titleLvl) {
String order = "";
if("0".equals(titleLvl)||Integer.parseInt(titleLvl)==8){//文档标题||正文
return "";
}else if(Integer.parseInt(titleLvl)>0&&Integer.parseInt(titleLvl) |